package aliyun

import (
	"encoding/json"
	"errors"
	"io"
	"net/http"
	"net/url"
	"sieve_engine/lib/config"
	"sieve_engine/lib/log"
	"sieve_engine/lib/util/convert"
	"sieve_engine/lib/util/rand"
	"sort"
	"strings"
	"time"
)

var (
	fAccessKeyId     = config.String("aliyun.accesskey.id", "", "阿里云 AccessKey ID")
	fAccessKeySecret = config.String("aliyun.accesskey.secret", "", "阿里云 AccessKey Secret")
	fRegion          = config.String("aliyun.region", "cn-shenzhen", "阿里云 RegionId")
	fDebug           = config.Bool("aliyun.debug", false, "阿里云 打印返回值")
)

func SetRegion(region string) {
	*fRegion = region
}

func SetAccessKey(id, secret string) {
	*fAccessKeyId = id
	*fAccessKeySecret = secret
}

func AccessKeyId() string {
	return *fAccessKeyId
}

func AccessKeySecret() string {
	return *fAccessKeySecret
}

func Region() string {
	return *fRegion
}

func CreateSignUrl_RPC(data url.Values) string {
	data.Set("AccessKeyId", *fAccessKeyId)
	data.Set("SignatureMethod", "HMAC-SHA1")
	data.Set("SignatureVersion", "1.0")
	data.Set("SignatureNonce", rand.RandStr(16))
	keys := []string{}
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	vals := []string{}
	for _, k := range keys {
		vals = append(vals, url_encode(k)+"="+url_encode(data.Get(k)))
	}
	data.Set("Signature", hmac_sha1("GET&%2F&"+url_encode(strings.Join(vals, "&"))))
	return data.Encode()
}

func CreateSignUrl_REST(data url.Values) string {
	return ""
}

func ReqApi(endpoint string, action string, req map[string]any, ret any) error {
	args := url.Values{}
	args.Set("Action", action)
	args.Set("Format", "JSON")
	args.Set("Version", "2014-05-15")
	args.Set("Timestamp", time.Now().UTC().Format(time.RFC3339))
	for k, v := range req {
		args.Set(k, convert.ToString(v))
	}
	resp, err := http.Get("https://" + endpoint + "/?" + CreateSignUrl_RPC(args))
	if err != nil {
		return err
	}
	b, err := io.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		return err
	}
	if resp.StatusCode != http.StatusOK {
		return errors.New("request failed " + string(b))
	}
	if ret == nil {
		return nil
	}
	err = json.Unmarshal(b, &ret)
	if err == nil && *fDebug {
		log.Debug(string(b))
	}
	return err
}
